package com.xjscrm.console.web.login;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.http.ContentType;
import com.xjscrm.common.exception.BusinessException;
import com.xjscrm.common.result.ResponseCode;
import com.xjscrm.console.anno.NoResponseResult;
import com.xjscrm.console.common.util.TokenUitls;
import com.xjscrm.console.constant.WxLoginAuthorizationPage;
import com.xjscrm.console.param.BaseDto;
import com.xjscrm.console.param.login.*;
import com.xjscrm.console.service.common.login.LoginService;
import com.xjscrm.console.service.customer.childLogin.ChildLoginService;
import com.xjscrm.console.vo.LoginUserByCode;
import com.xjscrm.console.vo.LoginVO;
import com.xjscrm.console.web.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Api(value = "登录管理", tags = "登录管理")
@RestController
@RequestMapping(value = "/login")
public class LoginController extends BaseController {

    @Autowired
    private LoginService loginService;

    @Autowired
    private ChildLoginService childLoginService;

    @Autowired
    private TokenUitls tokenUitls;

    @Autowired
    private RedisTemplate redisTemplate;

    private static Logger logger= LoggerFactory.getLogger(LoginController.class);


    @ApiOperation(value = "主账号注册", notes = "主账号注册",response = LoginVO.class)
    @PostMapping(value ="/register")
    public Object register(@RequestBody RegisterDto registerDto) throws Exception{
        return loginService.register(registerDto);
    }

    @ApiOperation(value = "主账号账密登录", notes = "账密登录",response = LoginVO.class)
    @PostMapping(value ="/loginByPwd")
    public Object loginByPwd(@RequestBody LoginByPwdDto loginByPwdDto)throws Exception{
       return loginService.loginByPwd(loginByPwdDto);
    }

    @ApiOperation(value = "主账号验证码登录", notes = "主账号验证码登录",response = LoginVO.class)
    @PostMapping(value ="/loginByCode")
    public Object loginByCode(@RequestBody LoginByCodeDto loginByCodeDto)throws Exception{
      return loginService.loginByCode(loginByCodeDto);
    }

    @ApiOperation(value = "子账号账密登录", notes = "主账号验证码登录",response = LoginVO.class)
    @PostMapping(value ="/childLoginByPwd")
    public Object childLoginByPwd(@RequestBody ChildLoginByPwdDto childLoginByPwdDto)throws Exception{
        return childLoginService.childLoginByPwd(childLoginByPwdDto);
    }

    @ApiOperation(value = "主账号密码找回", notes = "主账号密码找回",response = LoginVO.class)
    @PostMapping(value ="/getBackPassword")
    public Object getBackPassword(@RequestBody GetBackPasswordDto getBackPasswordDto)throws Exception{
        return loginService.getBackPassword(getBackPasswordDto);
    }

    @ApiOperation(value = "退出登录", notes = "退出登录",response = Boolean.class)
    @PostMapping(value ="/loginOut")
    public Object loginOut()throws Exception{
        tokenUitls.loginOut(getRequest());
        return true;
    }

    @ApiOperation(value = "刷新token", notes = "刷新token",response = LoginVO.class)
    @PostMapping(value ="/refreshToken")
    public Object refreshToken()throws Exception{
       return  tokenUitls.refreshToken(getRequest());
    }

    @ApiOperation(value = "生成微信登录的二维码", notes = "生成微信登录的二维码",response = String.class)
    @PostMapping(value ="/getWxLoginQrCode")
    public Object getWxLoginQrCode(@RequestBody QrCodeDto qrCodeDto)throws Exception{
        return  loginService.getWxLoginQrCode(qrCodeDto);
    }


    @ApiOperation(value = "主账号微信扫码登录授权", notes = "主账号微信扫码登录授权")
    @GetMapping(value ="/wxLogin")
    @NoResponseResult
    public Object wxLogin(@RequestParam String code, String state, HttpServletResponse response) throws Exception {
        logger.info("扫码登录进来：code={},state={}",code,state);

        response.setContentType(ContentType.TEXT_HTML.getValue());

        WxLogin wxLogin = new WxLogin();
        Map entries = redisTemplate.opsForHash().entries(state);
        LoginUserByCode loginUserByCode = BeanUtil.mapToBean(entries, LoginUserByCode.class, true);
        try {
            if (loginUserByCode != null && loginUserByCode.getType() != null) {
                wxLogin.setCode(code);
                wxLogin.setState(loginUserByCode.getType());
                if (loginUserByCode.getType() != null && loginUserByCode.getType().equals("1")) {
                    wxLogin.setMerId(loginUserByCode.getMerId());
                }
            } else {
                throw new BusinessException(ResponseCode.NULL_USERINFO, "未获取到用户信息");
            }

            LoginVO loginVO = loginService.wxLogin(wxLogin);
            if (loginVO != null) {
                if (loginVO.getId() != null) {
                    //登录
                    loginUserByCode.setLoginVO(loginVO);
                    loginUserByCode.setStatus(1);
                    redisTemplate.opsForHash().putAll(state, BeanUtil.beanToMap(loginUserByCode));
                    redisTemplate.expire(state, 120, TimeUnit.SECONDS);
                    IoUtil.write(response.getOutputStream(), true, WxLoginAuthorizationPage.successResponse.getBytes(StandardCharsets.UTF_8));
                    return null;

                } else {
                    loginUserByCode.setStatus(1);
                    redisTemplate.opsForHash().putAll(state, BeanUtil.beanToMap(loginUserByCode));
                    redisTemplate.expire(state, 120, TimeUnit.SECONDS);
                    IoUtil.write(response.getOutputStream(), true, WxLoginAuthorizationPage.successResponse.getBytes(StandardCharsets.UTF_8));
                    return null;

                }
            }

            loginUserByCode.setStatus(2);
            loginUserByCode.setErrMsg("请求和回调的状态不正确");
            redisTemplate.opsForHash().putAll(state, BeanUtil.beanToMap(loginUserByCode));
            redisTemplate.expire(state, 120, TimeUnit.SECONDS);
            IoUtil.write(response.getOutputStream(), true, WxLoginAuthorizationPage.failResponse.getBytes(StandardCharsets.UTF_8));
            return null;
        } catch (Exception e) {

            loginUserByCode.setStatus(2);
            loginUserByCode.setErrMsg(e.getMessage());
            redisTemplate.opsForHash().putAll(state, BeanUtil.beanToMap(loginUserByCode));
            redisTemplate.expire(state, 120, TimeUnit.SECONDS);
            IoUtil.write(response.getOutputStream(), true, WxLoginAuthorizationPage.failResponse.getBytes(StandardCharsets.UTF_8));
            return null;

        }


    }

    @ApiOperation(value = "主账号微信登录", notes = "主账号微信扫码登录",response = String.class)
    @GetMapping(value ="/wxLoginLoop")
    public Object wxLoginLoop(@RequestParam String state)throws Exception{
        logger.info("扫码登录进来：state={}",state);
        Map entries = redisTemplate.opsForHash().entries(state);
        if(entries==null){
            return null;
        }
        LoginUserByCode loginUserByCode = BeanUtil.mapToBean(entries, LoginUserByCode.class, true);
        if(loginUserByCode!=null&&loginUserByCode.getStatus()!=null&&loginUserByCode.getStatus().equals(1)){
            //登录
           if( loginUserByCode.getType()!=null&& loginUserByCode.getType().equals("0")){
               if(loginUserByCode.getLoginVO()==null){
                   throw new BusinessException(ResponseCode.NULL_USERINFO, "未获取到用户信息");
               }
               return loginUserByCode.getLoginVO();
           }
            //绑定微信
           if( loginUserByCode.getType()!=null&& loginUserByCode.getType().equals("1")){
               return 1;
           }

        } else if (loginUserByCode != null && loginUserByCode.getStatus() != null && loginUserByCode.getStatus().equals(2)) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, loginUserByCode.getErrMsg());
        }else {
            return null;
        }
        return null;
    }


    @ApiOperation(value = "主账号设置密码", notes = "主账号微信扫码登录",response = Boolean.class)
    @PostMapping(value ="/setPwd")
   public Object setPwd(@RequestBody SetPwdDto setPwdDto)throws Exception{
        loginService.setPwd(setPwdDto);
        return true;
   }

    @ApiOperation(value = "主账号更换手机号", notes = "主账号更换手机号",response = Boolean.class)
    @PostMapping(value ="/changePhone")
   public Object changePhone(@RequestBody ChangePhoneDto changePhoneDto)throws Exception{
       loginService.changePhone(changePhoneDto);
       return  true;
   }

    @ApiOperation(value = "主账号修改密码", notes = "主账号修改密码",response = Boolean.class)
    @PostMapping(value ="/changePwd")
   public Object changePwd(@RequestBody ChangePwdDto changePwdDto)throws Exception{
        loginService.changePwd(changePwdDto);
        return true;
   }

    @ApiOperation(value = "解除微信绑定", notes = "解除微信绑定", response = Boolean.class)
    @PostMapping(value = "/unbindWechat")
    public Object unbindWechat(@RequestBody BaseDto baseDto) throws Exception {
        loginService.unbindWechat(baseDto);
        return true;
    }
}
